﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using DT = CPPEI.Coolzon.Designtime.Metadata;

namespace CPPEI.Coolzon.Designer.Views
{
    class SolutionTreeViewNodeConverter
    {
        public delegate void UpdateStatus(SolutionTreeViewNode node);

        /// <summary>
        /// 将Designtime.Metadata.Solution转换为SolutionTreeViewNode对象
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="updateStatus">状态更新委托，在这里完成状态的更新操作</param>
        /// <returns></returns>
        public static SolutionTreeViewNode Convert(DT.Solution solution,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = solution.ID;
            node.ParentID = Guid.Empty;
            node.NodeType = NodeType.Solution;
            node.Name = solution.Name;
            node.Caption = solution.Caption;
            node.FolderID = solution.ID;
            updateStatus(node);

            ConvertFolder(node, solution, updateStatus);

            ConvertSceneInFolder(node, solution, updateStatus);

            //获取目录里的资源文件
            ConvertResourceInFolder(node, solution, updateStatus);

            return node;
        }

        /// <summary>
        /// 将场景对象转换为SolutionTreeViewNode对象
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="updateStatus">状态更新委托，在这里完成状态的更新操作</param>
        /// <returns></returns>
        public static SolutionTreeViewNode Convert(DT.Scene scene,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = scene.ID;
            node.ParentID = scene.ParentId;
            node.NodeType = NodeType.Scene;
            node.Name = scene.Name;
            node.Caption = scene.Caption;
            node.FolderID = scene.FolderId;
            updateStatus(node);
            return node;
        }

        public static SolutionTreeViewNode Convert(DT.Resource resource,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = resource.Id;
            node.ParentID = resource.FolderId;
            node.NodeType = NodeType.Resource;
            node.Name = string.Format("{0}.{1}", resource.FileName, resource.Extension);
            node.Caption = node.Name;
            node.FolderID = resource.FolderId;
            node.Extension = resource.Extension;
            updateStatus(node);
            return node;
        }

        public static SolutionTreeViewNode Convert(DT.Folder folder,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = folder.Id;
            node.ParentID = folder.FolderId;
            node.NodeType = NodeType.Folder;
            node.Name = folder.Name;
            node.Caption = folder.Name;
            node.FolderID = folder.FolderId;
            updateStatus(node);
            return node;
        }

        public static SolutionTreeViewNode Convert(DT.Template template,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = template.ID;
            node.ParentID = template.SceneID;
            node.NodeType = NodeType.Template;
            node.Name = template.Name;
            node.Caption = template.Name;
            DT.Scene scene = DT.SolutionHelper.GetScene(UIContext.Current.CurrentSolution, template.SceneID);
            node.FolderID = scene.FolderId;
            updateStatus(node);
            return node;
        }

        public static SolutionTreeViewNode Convert(DT.StaticDataSource staticDataSource,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            SolutionTreeViewNode node = new SolutionTreeViewNode();
            node.ID = staticDataSource.Id;
            node.ParentID = staticDataSource.FolderId;
            node.FolderID = staticDataSource.FolderId;
            node.NodeType = NodeType.StaticDataSource;
            node.Name = staticDataSource.Name;
            node.Caption = staticDataSource.Name;
            node.Extension = "xml";

            updateStatus(node);
            return node;
        }

        /// <summary>
        /// 转换方案中的目录节点
        /// </summary>
        /// <param name="root"></param>
        /// <param name="solution"></param>
        private static void ConvertFolder(SolutionTreeViewNode root, DT.Solution solution,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < solution.Folders.Count; index++)
            {
                DT.Folder folder = solution.Folders[index];

                SolutionTreeViewNode node = new SolutionTreeViewNode();
                node.ID = folder.Id;
                node.ParentID = root.ID;
                node.FolderID = root.ID;
                node.NodeType = NodeType.Folder;
                node.Name = folder.Name;
                node.Caption = folder.Name;
                root.Children.Add(node);

                if(node.ID == DT.Solution.StaticDataFolderId)
                {
                    ConvertStaticDataSource(node, solution, updateStatus);
                }

                //获取目录里所有的目录
                ConvertFolderInFolder(node, solution, folder.Folders, updateStatus);

                //获取目录里所有的场景
                ConvertSceneInFolder(node, solution, updateStatus);

                //获取目录里的资源文件
                ConvertResourceInFolder(node, solution, updateStatus);

                //获取子目录
                //ConvertSubFolder(node, folder, updateStatus);

                updateStatus(node);
            }
        }

        private static void ConvertStaticDataSource(SolutionTreeViewNode parentNode, DT.Solution solution, UpdateStatus updateStatus)
        {
            foreach(var item in solution.StaticDataSources)
            {
                SolutionTreeViewNode node = new SolutionTreeViewNode();
                node.ID = item.Id;
                node.ParentID = parentNode.ID;
                node.FolderID = parentNode.ID;
                node.NodeType = NodeType.StaticDataSource;
                node.Name = item.Name;
                node.Caption = item.Name;
                node.Extension = "xml";
                parentNode.Children.Add(node);

                updateStatus(node);
            }
        }

        private static void ConvertFolderInFolder(SolutionTreeViewNode root, DT.Solution solution, DT.FolderCollection folders,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < folders.Count; index++)
            {
                DT.Folder folder = folders[index];

                SolutionTreeViewNode node = new SolutionTreeViewNode();
                node.ID = folder.Id;
                node.ParentID = root.ID;
                node.FolderID = root.ID;
                node.NodeType = NodeType.Folder;
                node.Name = folder.Name;
                node.Caption = folder.Name;
                root.Children.Add(node);

                //获取目录里所有的目录
                ConvertFolderInFolder(node, solution, folder.Folders, updateStatus);

                //获取目录里所有的场景
                ConvertSceneInFolder(node, solution, updateStatus);

                //获取目录里的资源文件
                ConvertResourceInFolder(node, solution, updateStatus);

                //获取子目录
                //ConvertSubFolder(node, folder, updateStatus);

                updateStatus(node);
            }
        }

        /// <summary>
        /// 将方案中的一级场景关联到对应的目录中
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="solution"></param>
        private static void ConvertSceneInFolder(SolutionTreeViewNode folder, DT.Solution solution,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < solution.Scenes.Count; index++)
            {
                DT.Scene scene = solution.Scenes[index];

                // 在目录里的场景就不可能是子场景
                if (scene.FolderId == folder.ID && scene.ParentId == solution.ID)
                {
                    SolutionTreeViewNode node = new SolutionTreeViewNode();
                    node.ID = scene.ID;
                    node.ParentID = scene.ParentId;
                    node.FolderID = scene.FolderId;
                    node.NodeType = NodeType.Scene;
                    node.Name = scene.Name;
                    node.Caption = scene.Caption;
                    updateStatus(node);

                    folder.Children.Add(node);

                    ConvertTemplate(node, scene, updateStatus);

                    ConvertSceneInScene(node, solution, updateStatus);
                }
            }
        }

        private static void ConvertTemplate(SolutionTreeViewNode node, DT.Scene scene, UpdateStatus updateStatus)
        {
            for(int index = 0; index < scene.Templates.Count; index++)
            {
                DT.Template template = scene.Templates[index];

                SolutionTreeViewNode templateNode = new SolutionTreeViewNode();
                templateNode.ID = template.ID;
                templateNode.ParentID = template.SceneID;
                templateNode.NodeType = NodeType.Template;
                templateNode.Name = template.Name;
                templateNode.Caption = template.Name;

                templateNode.FolderID = scene.FolderId;
                updateStatus(templateNode);

                node.Children.Add(templateNode);
            }
        }

        private static void ConvertSceneInScene(SolutionTreeViewNode parentSceneNode, DT.Solution solution,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < solution.Scenes.Count; index++)
            {
                DT.Scene scene = solution.Scenes[index];
                if (scene.ParentId == parentSceneNode.ID)
                {
                    SolutionTreeViewNode node = new SolutionTreeViewNode();
                    node.ID = scene.ID;
                    node.ParentID = scene.ParentId;
                    node.FolderID = scene.FolderId;
                    node.NodeType = NodeType.Scene;
                    node.Name = scene.Name;
                    node.Caption = scene.Caption;
                    updateStatus(node);

                    parentSceneNode.Children.Add(node);

                    ConvertTemplate(node, scene, updateStatus);

                    ConvertSceneInScene(node, solution, updateStatus);
                }
            }
        }

        /// <summary>
        /// 转换资源文件到目录中
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="solution"></param>
        private static void ConvertResourceInFolder(SolutionTreeViewNode folder, DT.Solution solution,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < solution.Resources.Count; index++)
            {
                DT.Resource resource = solution.Resources[index];
                if (resource.FolderId == folder.ID)
                {
                    SolutionTreeViewNode node = new SolutionTreeViewNode();
                    node.ID = resource.Id;
                    node.FolderID = resource.FolderId;
                    node.ParentID = resource.FolderId;
                    node.NodeType = NodeType.Resource;
                    node.Name = string.Format("{0}.{1}", resource.FileName, resource.Extension);
                    node.Caption = node.Name;
                    node.Extension = resource.Extension;
                    updateStatus(node);

                    folder.Children.Add(node);
                }
            }
        }

        /// <summary>
        /// 转换子目录
        /// </summary>
        /// <param name="parentNode"></param>
        /// <param name="parentFolder"></param>
        private static void ConvertSubFolder(SolutionTreeViewNode parentNode, DT.Folder parentFolder,
            SolutionTreeViewNodeConverter.UpdateStatus updateStatus)
        {
            for (int index = 0; index < parentFolder.Folders.Count; index++)
            {
                DT.Folder folder = parentFolder.Folders[index];
                SolutionTreeViewNode node = new SolutionTreeViewNode();
                node.ID = folder.Id;
                node.FolderID = folder.FolderId;
                node.ParentID = folder.FolderId;
                node.NodeType = NodeType.Folder;
                node.Name = folder.Name;
                node.Caption = folder.Name;

                updateStatus(node);

                parentNode.Children.Add(node);

                ConvertSubFolder(node, folder, updateStatus);
            }
        }
    }
}
